package com.app.shop.util;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.UUID;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * @Title
 * @Description (缩略图 工具类)
 * @author Garfield Miao
 * @date 2019年21月03日
 * @upAuthor Garfield Miao
 * @update 2019年21月03日
 */
public class ImageCompressionUtil {

	private static final Logger LOG = LogManager
			.getLogger(ImageCompressionUtil.class);

	/**
	 * 对指定的图片进行压缩
	 * 
	 * @param imageFile
	 * @param quality
	 * @return
	 */
	public static File compressFile(File imageFile, float quality) {
		InputStream is = null;
		OutputStream os = null;
		ImageOutputStream ios = null;
		ImageWriter writer = null;

		try {
			// File imageFile = new
			// File("C:\\Users\\AnandhKumar_J\\Pictures\\Capture.PNG");
			String fileExt = FilenameUtils.getExtension(imageFile.getName());

			File compressedImageFile = File.createTempFile(UUID.randomUUID()
					.toString(), "." + fileExt);

			is = new FileInputStream(imageFile);
			os = new FileOutputStream(compressedImageFile);

			// float quality = 1.0f;

			// create a BufferedImage as the result of decoding the supplied
			// InputStream
			BufferedImage image = ImageIO.read(is);

			// get all image writers for JPG format
			Iterator<ImageWriter> writers = ImageIO
					.getImageWritersByFormatName(fileExt);

			if (!writers.hasNext()) {
				throw new IllegalStateException("No writers found");
			}

			writer = (ImageWriter) writers.next();
			ios = ImageIO.createImageOutputStream(os);
			writer.setOutput(ios);

			ImageWriteParam param = writer.getDefaultWriteParam();

			// compress to a given quality
			param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
			param.setCompressionQuality(quality);

			// appends a complete image stream containing a single image and
			// associated stream and image metadata and thumbnails to the output
			writer.write(null, new IIOImage(image, null, null), param);

			return compressedImageFile;
		} catch (Exception e) {
			LOG.error(e);
			return imageFile;
		} finally {
			// close all streams
			try {
				if (is != null) {
					is.close();
				}
				if (os != null) {
					os.close();
				}
				if (ios != null) {
					ios.close();
				}
				if (writer != null) {
					writer.dispose();
				}
			} catch (IOException e) {
				LOG.error("Error While Doing image Compression ",e);
			}

		}
	}

	/**
	 * 压缩图片
	 * 
	 * @param imageFile
	 * @returnn
	 */
	public static File compressFile(File file) {
		return compressFile(file, 0.7f);
	}
	public static void Tosmallerpic(BufferedImage src, String outImgPath,  
            int new_w, int new_h, float per,int angel) throws IOException {  
		//BufferedImage  src = ImageIO.read(srcInputStream); 
        int old_w = src.getWidth();  
        // 得到源图宽  
        int old_h = src.getHeight();  
        // 得到源图长  
        // 根据原图的大小生成空白画布  
        BufferedImage tempImg = new BufferedImage(old_w, old_h,  
                BufferedImage.TYPE_INT_RGB);  
        // 在新的画布上生成原图的缩略图  
        Graphics2D g = tempImg.createGraphics();  
        g.setColor(Color.white);  
        g.fillRect(0, 0, old_w, old_h);  
        g.drawImage(src, 0, 0, old_w, old_h, Color.white, null);  
        g.dispose();  
        BufferedImage newImg = new BufferedImage(new_w, new_h,  
                BufferedImage.TYPE_INT_RGB);  
        newImg.getGraphics().drawImage(  
                tempImg.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0,  
                0, null);        
        // 调用方法输出图片文件  
        OutImage(outImgPath, newImg, per);  
    }  
	
	
	public static void newTosmallerpic(BufferedImage src, String outImgPath,  
            String fileExt, float per,int angel) throws IOException {  
		//BufferedImage  src = ImageIO.read(srcInputStream); 
        // 调用方法输出图片文件  
        //OutImage(outImgPath, newImg, per);  
        
    	Integer min = null;
		Integer max = null;
		// 得到源图宽  
		int old_w = src.getWidth();  
		// 得到源图长  
	    int old_h = src.getHeight();  

		if (old_w > old_h) {
			min = old_h;
			max = old_w;
			Image image = src.getScaledInstance(src.getWidth(), src.getHeight(), Image.SCALE_DEFAULT);
			// 四个参数分别为图像起点坐标和宽高
			// 即: CropImageFilter(int x,int y,int width,int height)
			ImageFilter cropFilter = new CropImageFilter((max - min) / 2, 0, min, min);
			Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
			BufferedImage tag = new BufferedImage(src.getHeight(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(img, 0, 0, src.getHeight(), src.getHeight(), null); // 绘制切割后的图
			FileOutputStream fileOut = new FileOutputStream(outImgPath);
			ImageIO.write(tag, fileExt, fileOut);
		} else if (old_w < old_h) {
			min = old_w;
			max = old_h;
			LOG.info("min:" + min);
			LOG.info("max:" + max);
			Image image = src.getScaledInstance(src.getWidth(), src.getHeight(), Image.SCALE_DEFAULT);
			// 四个参数分别为图像起点坐标和宽高
			// 即: CropImageFilter(int x,int y,int width,int height)
			ImageFilter cropFilter = new CropImageFilter(0, (max - min) / 2, old_w, old_w);
			Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
			BufferedImage tag = new BufferedImage(src.getHeight(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(img, 0, 0, src.getHeight(), src.getHeight(), null); // 绘制切割后的图
			FileOutputStream fileOut = new FileOutputStream(outImgPath);
			ImageIO.write(tag, fileExt, fileOut);
		} else {
			min = old_w;
			max = old_h;
			Image image = src.getScaledInstance(src.getWidth(), src.getHeight(), Image.SCALE_DEFAULT);
			// 四个参数分别为图像起点坐标和宽高
			// 即: CropImageFilter(int x,int y,int width,int height)
			ImageFilter cropFilter = new CropImageFilter(0, (max - min) / 2, min, min);
			Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
			BufferedImage tag = new BufferedImage(src.getHeight(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(img, 0, 0, src.getHeight(), src.getHeight(), null); // 绘制切割后的图
			FileOutputStream fileOut = new FileOutputStream(outImgPath);
			ImageIO.write(tag, fileExt, fileOut);
			// ImageIO.write(tag, "JPEG", file);
		}
        
    }  
	
	
 private static void OutImage(String outImgPath, BufferedImage newImg,  
            float per) {  
        // 判断输出的文件夹路径是否存在，不存在则创建  
        File file = new File(outImgPath);  
        if (!file.getParentFile().exists()) {  
            file.getParentFile().mkdirs();  
        }// 输出到文件流  
        try {  
            FileOutputStream newimage = new FileOutputStream(outImgPath);  
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);  
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(newImg);  
            // 压缩质量  
            jep.setQuality(per, true);  
            encoder.encode(newImg, jep);  
            newimage.close();  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch blocke.printStackTrace();  
        } catch (ImageFormatException e) {  
            // TODO Auto-generated catch blocke.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch blocke.printStackTrace();  
        }  
    }  
 
 
 /**
	* 计算旋转参数
	*/
	public static Rectangle CalcRotatedSize(Rectangle src,int angel){
		// if angel is greater than 90 degree,we need to do some conversion.
		if(angel > 90){
			if(angel / 9%2 ==1){
				int temp = src.height;
				src.height = src.width;
				src.width = temp;
			}
			angel = angel % 90;
		}
		
		double r = Math.sqrt(src.height * src.height + src.width * src.width ) / 2 ;
		double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
		double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;  
		double angel_dalta_width = Math.atan((double) src.height / src.width);  
		double angel_dalta_height = Math.atan((double) src.width / src.height);  

		int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha  
				- angel_dalta_width));  
		int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha  
				- angel_dalta_height));  
		int des_width = src.width + len_dalta_width * 2;  
		int des_height = src.height + len_dalta_height * 2;  
		return new Rectangle(new Dimension(des_width, des_height));
	}
}
